package cn.lut.crowd.handler;

import cn.lut.constant.CrowdConstant;
import cn.lut.crowd.api.MySQLRemoteService;
import cn.lut.crowd.api.RedisRemoteService;
import cn.lut.crowd.config.ShortMessageProperties;
import cn.lut.crowd.entity.po.MemberPO;
import cn.lut.crowd.entity.vo.MemberLoginVO;
import cn.lut.crowd.entity.vo.MemberVO;
import cn.lut.util.CrowdUtil;
import cn.lut.util.ResultEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @user:dell
 * @date:2021年01月08 14:12
 */
@Controller
public class MemberHandler {
    @Autowired
    private ShortMessageProperties shortMessageProperties;
    @Autowired
    private RedisRemoteService redisRemoteService;
    @Autowired
    private MySQLRemoteService mySQLRemoteService;
//    退出登录
    @RequestMapping("/auth/member/logout")
    public String logout(HttpSession session){
        session.invalidate();
        return "redirect:/";
    }
//    登录
    @RequestMapping("/auth/member/do/login")
    public String login(@RequestParam("loginacct")String loginacct, @RequestParam("userpswd") String userpswd, ModelMap modelMap, HttpSession session){
        ResultEntity<MemberPO> resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginacct);
        if(ResultEntity.FAILED.equals(resultEntity.getResult())){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,resultEntity.getMessage());
            return "member-login";
        }
        MemberPO memberPO = resultEntity.getData();
        if(memberPO==null){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
//        2.比较密码
        String userpswdDataBase = memberPO.getUserpswd();
        BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        boolean matchesResult = passwordEncoder.matches(userpswd, userpswdDataBase);
        if(!matchesResult){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
//        存入session域中
session.setAttribute("loginMember",memberLoginVO);
//return "redirect:/auth/member/to/center/page";
        return "redirect:http://localhost:88/auth/member/to/center/page";
    }
//  注册
    @RequestMapping("/auth/member/register")
    public String register(MemberVO memberVO, ModelMap modelMap) {
//        1.获取用户输入手机号
        String phoneNum = memberVO.getPhoneNum();
//        2.拼Redis中存储验证码的key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
//        3.从redis读取key对应的value
        ResultEntity<String> resultEntity = redisRemoteService.getRedisStringValueByKeyRemote(key);
//        4.检查查询操作是否有效
        String result = resultEntity.getResult();
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
            return "member-reg";
        }
        String redisCode = resultEntity.getData();
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
            return "member-reg";
        }
        //        5.如果从redis能够查到value则比较表单验证码和redis验证码
        String formCode = memberVO.getCode();
        if (!Objects.equals(formCode, redisCode)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";
        }
//        6.如果验证码一致，则从redis删除
        ResultEntity<String> removeResultEntity = redisRemoteService.removeRedisKeyRemote(key);
        //        7.执行密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String userpswd = memberVO.getUserpswd();
        String userPswdAfterEncode = passwordEncoder.encode(userpswd);
        memberVO.setUserpswd(userPswdAfterEncode);
        //        8.执行保存
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVO, memberPO);
        ResultEntity<String> saveMemberEntity = mySQLRemoteService.saveMember(memberPO);
        if(ResultEntity.FAILED.equals(saveMemberEntity)){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMemberEntity.getMessage());
            return "member-reg";
        }
        return "redirect:/auth/member/to/login/page.html";
    }
//发短信
    @RequestMapping("/auth/member/send/short/message.json")
    @ResponseBody
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {
//        1.发送验证码到指定手机phoneNum
        ResultEntity<String> sendMessageResultEntity = CrowdUtil.sendShortMessage(shortMessageProperties.getHost(), shortMessageProperties.getPath(), shortMessageProperties.getMethod(), phoneNum, shortMessageProperties.getAppCode());
//        2.判断短信发送的结果
        if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {
            // 3.如果发送成功，则将验证码存入Redis
            String code = sendMessageResultEntity.getData();
//            用于在redis中存取的key
            String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
            if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
                return ResultEntity.successWithOutData();
            } else {
                return saveCodeResultEntity;
            }
        } else {
            return sendMessageResultEntity;
        }
    }
}
